// 导入封装的本地存储操作模块
import { getStorageSync } from './storage';
// 创建 WxRequest 类
class WxRequest {

  // 定义实例属性，用来设置默认请求参数
  defaults = {
    baseURL : '', // 请求基准地址
    url:'',//接口请求路径
    data:null, //请求参数
    method:'GET',
    //请求头
    header:{
      "Content-type":"application/json" //数据的交互格式
    },
    timeout:60000,
  }
  // 定义拦截器对象
  // 请求拦截器以及响应拦截器，方便在请求之前以及响应以后进行逻辑处理
  interceptors = {
    // 请求拦截器
    //在请求发送之前，对请求参数进行新增或者修改
    request: (config) =>  config,
// 响应拦截器
// 服务器响应以后，对服务器响应的数据进行逻辑处理
   response:(response) => response
  }




  // 用于创建和初始化类的属性和方法
  // 在实例化时传入的参数，会被constructor 形参进行接收
  constructor (params = {}) {
    // 通过Object.assign 方法合并请求参数，传入的参数会覆盖默认参数，因此传入的参数需要放到最后
  this.defaults = Object.assign({},this.defaults,params)
  }
  // request 实例方法接收一个对象类型的参数
  request(options){
    // 需要先合并完整请求地址
    options.url = this.defaults.baseURL + options.url
    // 合并请求参数
    options = { ...this.defaults,...options}

// 在请求发送之前，调用请求拦截器，新增和修改参数
options = this.interceptors.request(options)



    // 需要使用Promise 封装 wx.request ,处理异步请求
    return new Promise((resolve,reject) => {
      wx.request({
        ...options,
        // 当接口成功会触发success回调函数
        success: (res) => {
          // 不管是成功响应还是失败响应，都需要调用响应拦截器
          // 响应拦截器需要接收服务器响应的数据，然后对数据进行逻辑处理，处理好以后进行返回
          //然后再通过 resolve 将返回的数据抛出去

          // 再给响应拦截器传递参数时，需要将请求参数也一起传递，方便进行代码的调试或者进行其他逻辑处理，需要先合并参数
          //然后将合并的参数传递给响应拦截器
         const mergeRes =  Object.assign({},res,{config:options})
          resolve(this.interceptors.request(mergeRes))
        },
        // 当接口失败时会触发fail回调函数
        fail: (err) => {
          // 不管是成功响应还是失败响应，都需要调用响应拦截器
          const mergeErr =  Object.assign({},err,{config:options})
          resolve(this.interceptors.request(mergeErr))
        }
      })


    })
  }
  //封装四个请求方法
  // 封装GET 实例方法
  // 需要调用 request 请求方法发送请求，只需要组织好参数，传递给request 请求方法即可
  // 当调用 get 方法时，需要把 request 方法的返回值 return 出去
  get(url,data={},config={}) {
    return this.request(Object.assign({url,data,method:'GET'},config))
  }
  // 封装DELETE 实例方法
  delete(url,data={},config={}) {
    return this.request(Object.assign({url,data,method:'DELETE'},config))
  }
  // 封装POST 实例方法
  post(url,data={},config={}) {
    return this.request(Object.assign({url,data,method:'POST'},config))
  }
  // 封装PUT 实例方法
  put(url,data={},config={}) {
    return this.request(Object.assign({url,data,method:'PUT'},config))
  }

}

// 以下是实例化的代码
const instance = new WxRequest({
  baseURL:'http://localhost:9000',
  timeout:15000
})

//配置请求拦截器
instance.interceptors.request = (config) => {
  // 请求发送之前做点什么
    // 将 token 添加到请求头
    const token = getStorageSync('token');
    if (token) {
      config.header['token'] = token;
    }
  return config
}
//配置响应拦截器
instance.interceptors.request = (response) => {
  // 对服务器响应数据做点什么
  return response
}


// 暴露出去
export default instance